package dubbo_imitate

type (
	invoker interface {
		invoke(invocation) (string, error)
	}

	invocation struct {
		name string
	}

	interceptor interface {
		before(ivk invoker, inv invocation)
		intercept(ivk invoker, inv invocation) (string, error)
		after(ivk invoker, inv invocation)
	}
)

func buildInterceptors(ivk invoker, interceptors []interceptor) invoker {
	last := ivk
	if len(interceptors) != 0 {
		for i := len(interceptors) - 1; i >= 0; i-- {
			curInterceptor := interceptors[i]
			next := last
			last = &InterceptorInvoker{
				interceptor: curInterceptor,
				next:        next,
			}
		}
	}
	return last
}

type InterceptorInvoker struct {
	interceptor interceptor
	next        invoker
}

func (i *InterceptorInvoker) invoke(inv invocation) (string, error) {
	i.interceptor.before(i.next, inv)
	defer i.interceptor.after(i.next, inv)

	res, err := i.interceptor.intercept(i.next, inv)
	return res, err

}
